package com.jake.spring.lifecycle.domain;

import com.jake.spring.lifecycle.service.SchoolService;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;

@Data
@Slf4j
public class Person implements BeanNameAware, BeanFactoryAware, InitializingBean, ApplicationContextAware, DisposableBean {

    @Autowired
    private SchoolService schoolService;

    static {
        log.info("static block");
    }

    private static StaticField staticField = new StaticField();

    {
        log.info("block");
    }

    private String name;

    public Person() {
//        schoolService.gotoSchool(); //不支持在这里调用注入Bean
        log.info("constructor: Instantiate");
    }

    public void setName(String name) {
//        schoolService.gotoSchool(); //不支持在这里调用注入Bean
        log.info("setter: populate property, {}", name);
        this.name = name;
    }

    public String getName() {
        log.info("getter");
        return name;
    }

    @Override
    public void setBeanName(String beanName) {
        schoolService.gotoSchool();
        log.info("setBeanName: " + beanName);
    }

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        log.info("setBeanFactory: {}", beanFactory.getClass());
    }

    /**
     * InitializingBean的方法
     * 作用是在Spring所有Bean加载完成后，执行此方法完成一些数据初始化的工作，参考：https://blog.csdn.net/TUTsmile/article/details/107463998
     */
    @Override
    public void afterPropertiesSet() {
        log.info("afterPropertiesSet");
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        log.info("setApplicationContext: {}", applicationContext);
    }

    @Override
    public void destroy() {
        log.info("destroy");
    }

    public void customInit() {
        log.info("customInit");
    }

    public void customDestroy() {
        log.info("customDestroy");
    }

    @PostConstruct
    public void postConstruct() {
        log.info("post construct");
    }

    @PreDestroy
    public void preDestroy() {
        log.info("pre destroy");
    }
}
